package com.harmony.pilot.knowledge.service;

import com.google.gson.Gson;
import com.harmony.pilot.knowledge.entity.GniFile;
import com.harmony.pilot.knowledge.repository.GniFileRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * GNI文件解析服务
 * 解析和分析.gni配置文件
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GniFileService {
    
    private final GniFileRepository gniFileRepository;
    private final Gson gson = new Gson();
    
    @Value("${openharmony.code.base-path:../ohcode}")
    private String codeBasePath;
    
    // GNI文件中的import语句正则
    private static final Pattern IMPORT_PATTERN = Pattern.compile(
        "^\\s*import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)"
    );
    
    // 变量定义正则（简化版）
    private static final Pattern VARIABLE_PATTERN = Pattern.compile(
        "^\\s*(\\w+)\\s*=\\s*(.+)$"
    );
    
    /**
     * 解析.gni文件
     */
    public GniFile parseGniFile(String filePath) {
        log.info("Parsing .gni file: {}", filePath);
        
        try {
            Path path = Paths.get(filePath);
            String content = Files.readString(path);
            
            GniFile gniFile = new GniFile();
            gniFile.setFilePath(filePath);
            gniFile.setFileName(path.getFileName().toString());
            gniFile.setContent(content);
            
            // 提取模块名称
            String[] pathParts = filePath.replace("\\", "/").split("/");
            if (pathParts.length > 0) {
                gniFile.setModuleName(pathParts[Math.max(0, pathParts.length - 3)]);
            }
            
            // 解析import语句
            List<String> imports = extractImports(content);
            gniFile.setImports(gson.toJson(imports));
            
            // 解析变量定义
            Map<String, String> variables = extractVariables(content);
            gniFile.setVariables(gson.toJson(variables));
            
            return gniFile;
            
        } catch (IOException e) {
            log.error("Failed to parse .gni file: {}", filePath, e);
            return null;
        }
    }
    
    /**
     * 提取import语句
     */
    private List<String> extractImports(String content) {
        List<String> imports = new ArrayList<>();
        
        String[] lines = content.split("\n");
        for (String line : lines) {
            Matcher matcher = IMPORT_PATTERN.matcher(line);
            if (matcher.find()) {
                imports.add(matcher.group(1));
            }
        }
        
        return imports;
    }
    
    /**
     * 提取变量定义（简化版，实际GN语法更复杂）
     */
    private Map<String, String> extractVariables(String content) {
        Map<String, String> variables = new HashMap<>();
        
        String[] lines = content.split("\n");
        for (String line : lines) {
            line = line.trim();
            
            // 跳过注释和空行
            if (line.isEmpty() || line.startsWith("#") || line.startsWith("//")) {
                continue;
            }
            
            // 简单的变量定义提取
            Matcher matcher = VARIABLE_PATTERN.matcher(line);
            if (matcher.find()) {
                String varName = matcher.group(1);
                String varValue = matcher.group(2).trim();
                // 移除末尾的分号（如果有）
                if (varValue.endsWith(";")) {
                    varValue = varValue.substring(0, varValue.length() - 1).trim();
                }
                variables.put(varName, varValue);
            }
        }
        
        return variables;
    }
    
    /**
     * 扫描并解析所有.gni文件
     */
    public List<GniFile> scanAllGniFiles() {
        log.info("Scanning all .gni files...");
        
        List<GniFile> gniFiles = new ArrayList<>();
        
        try {
            Path basePath = Paths.get(codeBasePath);
            Files.walk(basePath)
                    .filter(Files::isRegularFile)
                    .filter(path -> path.getFileName().toString().endsWith(".gni"))
                    .forEach(path -> {
                        GniFile gniFile = parseGniFile(path.toString());
                        if (gniFile != null) {
                            gniFiles.add(gniFile);
                        }
                    });
            
            log.info("Found {} .gni files", gniFiles.size());
            
        } catch (IOException e) {
            log.error("Failed to scan .gni files", e);
        }
        
        return gniFiles;
    }
    
    /**
     * 保存或更新.gni文件
     */
    public GniFile saveGniFile(GniFile gniFile) {
        Optional<GniFile> existing = gniFileRepository.findByFilePath(gniFile.getFilePath());
        if (existing.isPresent()) {
            GniFile existingFile = existing.get();
            existingFile.setContent(gniFile.getContent());
            existingFile.setVariables(gniFile.getVariables());
            existingFile.setImports(gniFile.getImports());
            existingFile.setModuleName(gniFile.getModuleName());
            return gniFileRepository.save(existingFile);
        } else {
            return gniFileRepository.save(gniFile);
        }
    }
    
    /**
     * 根据模块查询
     */
    public List<GniFile> findByModuleName(String moduleName) {
        return gniFileRepository.findByModuleName(moduleName);
    }
    
    /**
     * 查找引用某个.gni文件的所有文件
     */
    public List<GniFile> findFilesImporting(String importedGniPath) {
        // TODO: 实现查询逻辑
        return new ArrayList<>();
    }
}

